#!/usr/bin/env python3
"""
Bacon MCP Server

面向 rubygem-bacon 软件的 MCP server，提供 bacon 命令行工具的封装功能。

MCP tools 列表：
1. bacon_help_version - 获取帮助信息和版本信息
   参数：help_option (str): 帮助选项，可选值：'-h', '--help', '--version'
   返回：统一 JSON 结构

2. bacon_run_test - 运行 bacon 测试
   参数：test_file (str): 测试文件路径
         option (str): 测试选项，可选值：'-s', '--specdox', '-q', '--quiet', '-p', '--tap', '-k', '--knock', '-o', '--output', '-Q', '--no-backtrace'
         output_format (str, 可选): 当 option 为 '-o' 或 '--output' 时指定的输出格式
   返回：统一 JSON 结构

3. bacon_automatic - 运行自动测试
   参数：option (str): 自动测试选项，可选值：'-a', '--automatic'
   返回：统一 JSON 结构

4. bacon_filter_test - 运行带名称过滤的测试
   参数：automatic_option (str): 自动测试选项，可选值：'-a', '--automatic'
         filter_option (str): 过滤选项，可选值：'-n', '--name'
         pattern (str): 过滤模式
   返回：统一 JSON 结构

5. bacon_debug_warn - 运行调试或警告模式测试
   参数：test_file (str): 测试文件路径
         tap_option (str): TAP 输出选项，固定为 '--tap'
         debug_option (str): 调试/警告选项，可选值：'-d', '--debug', '-w', '--warn'
   返回：统一 JSON 结构

6. bacon_include_require - 运行需要包含路径的测试
   参数：test_file (str): 测试文件路径
         include_option (str): 包含选项，可选值：'-I', '--include'
         include_path (str): 包含路径
         require_option (str): 加载选项，可选值：'-r', '--require'
         require_path (str): 加载路径
   返回：统一 JSON 结构

7. bacon_testcase - 运行特定测试用例
   参数：testcase_option (str): 测试用例选项，可选值：'-t', '--testcase'
         testcase_name (str): 测试用例名称
         test_file (str): 测试文件路径
   返回：统一 JSON 结构

所有工具返回的统一 JSON 结构：
{
  "success": bool,      # 命令是否成功执行
  "command": str,       # 执行的完整命令
  "exit_code": int,     # 命令退出码
  "stdout": str,        # 标准输出内容
  "stderr": str         # 标准错误内容
}
"""

import subprocess
import shlex
from typing import List, Optional
from mcp.server.fastmcp import FastMCP, Context

mcp = FastMCP("Bacon MCP Server")

@mcp.tool()
def bacon_help_version(help_option: str) -> dict:
    """
    获取 bacon 的帮助信息或版本信息
    
    参数:
        help_option: 帮助选项，可选值：'-h', '--help', '--version'
    
    返回:
        JSON 结构: {
            "success": bool,
            "command": str,
            "exit_code": int, 
            "stdout": str,
            "stderr": str
        }
    """
    command = f"bacon {help_option}"
    try:
        result = subprocess.run(
            shlex.split(command),
            capture_output=True,
            text=True,
            timeout=30
        )
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def bacon_run_test(test_file: str, option: str, output_format: Optional[str] = None) -> dict:
    """
    运行 bacon 测试
    
    参数:
        test_file: 测试文件路径
        option: 测试选项，可选值：'-s', '--specdox', '-q', '--quiet', '-p', '--tap', '-k', '--knock', '-o', '--output', '-Q', '--no-backtrace'
        output_format: 当 option 为 '-o' 或 '--output' 时指定的输出格式
    
    返回:
        JSON 结构: {
            "success": bool,
            "command": str,
            "exit_code": int,
            "stdout": str, 
            "stderr": str
        }
    """
    if option in ['-o', '--output'] and output_format:
        command = f"bacon {option} {output_format} {test_file}"
    else:
        command = f"bacon {option} {test_file}"
    
    try:
        result = subprocess.run(
            shlex.split(command),
            capture_output=True,
            text=True,
            timeout=60
        )
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def bacon_automatic(option: str) -> dict:
    """
    运行 bacon 自动测试模式
    
    参数:
        option: 自动测试选项，可选值：'-a', '--automatic'
    
    返回:
        JSON 结构: {
            "success": bool,
            "command": str,
            "exit_code": int,
            "stdout": str,
            "stderr": str
        }
    """
    command = f"bacon {option}"
    try:
        result = subprocess.run(
            shlex.split(command),
            capture_output=True,
            text=True,
            timeout=120
        )
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def bacon_filter_test(automatic_option: str, filter_option: str, pattern: str) -> dict:
    """
    运行带名称过滤的 bacon 测试
    
    参数:
        automatic_option: 自动测试选项，可选值：'-a', '--automatic'
        filter_option: 过滤选项，可选值：'-n', '--name'
        pattern: 过滤模式
    
    返回:
        JSON 结构: {
            "success": bool,
            "command": str,
            "exit_code": int,
            "stdout": str,
            "stderr": str
        }
    """
    command = f"bacon {automatic_option} {filter_option} {shlex.quote(pattern)}"
    try:
        result = subprocess.run(
            shlex.split(command),
            capture_output=True,
            text=True,
            timeout=120
        )
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def bacon_debug_warn(test_file: str, tap_option: str, debug_option: str) -> dict:
    """
    运行 bacon 调试或警告模式测试
    
    参数:
        test_file: 测试文件路径
        tap_option: TAP 输出选项，固定为 '--tap'
        debug_option: 调试/警告选项，可选值：'-d', '--debug', '-w', '--warn'
    
    返回:
        JSON 结构: {
            "success": bool,
            "command": str,
            "exit_code": int,
            "stdout": str,
            "stderr": str
        }
    """
    command = f"bacon {tap_option} {test_file} {debug_option}"
    try:
        result = subprocess.run(
            shlex.split(command),
            capture_output=True,
            text=True,
            timeout=60
        )
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def bacon_include_require(test_file: str, include_option: str, include_path: str, require_option: str, require_path: str) -> dict:
    """
    运行需要包含路径和加载库的 bacon 测试
    
    参数:
        test_file: 测试文件路径
        include_option: 包含选项，可选值：'-I', '--include'
        include_path: 包含路径
        require_option: 加载选项，可选值：'-r', '--require'
        require_path: 加载路径
    
    返回:
        JSON 结构: {
            "success": bool,
            "command": str,
            "exit_code": int,
            "stdout": str,
            "stderr": str
        }
    """
    command = f"bacon {test_file} {include_option} {include_path} {require_option} {require_path}"
    try:
        result = subprocess.run(
            shlex.split(command),
            capture_output=True,
            text=True,
            timeout=60
        )
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

@mcp.tool()
def bacon_testcase(testcase_option: str, testcase_name: str, test_file: str) -> dict:
    """
    运行特定 bacon 测试用例
    
    参数:
        testcase_option: 测试用例选项，可选值：'-t', '--testcase'
        testcase_name: 测试用例名称
        test_file: 测试文件路径
    
    返回:
        JSON 结构: {
            "success": bool,
            "command": str,
            "exit_code": int,
            "stdout": str,
            "stderr": str
        }
    """
    command = f"bacon {testcase_option} {shlex.quote(testcase_name)} {test_file}"
    try:
        result = subprocess.run(
            shlex.split(command),
            capture_output=True,
            text=True,
            timeout=60
        )
        return {
            "success": result.returncode == 0,
            "command": command,
            "exit_code": result.returncode,
            "stdout": result.stdout,
            "stderr": result.stderr
        }
    except Exception as e:
        return {
            "success": False,
            "command": command,
            "exit_code": -1,
            "stdout": "",
            "stderr": str(e)
        }

if __name__ == "__main__":
    mcp.run()